package com.easybbs.service.impl;

import java.io.File;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.easybbs.config.WebConfig;
import com.easybbs.constants.Constants;
import com.easybbs.entity.dto.FileUploadDto;
import com.easybbs.entity.dto.SysSetting4AuditDto;
import com.easybbs.entity.enums.*;
import com.easybbs.entity.po.ForumArticle;
import com.easybbs.entity.po.ForumBoard;
import com.easybbs.entity.query.ForumArticleQuery;
import com.easybbs.exception.BusinessException;
import com.easybbs.mappers.ForumArticleMapper;
import com.easybbs.service.ForumBoardService;
import com.easybbs.service.UserInfoService;
import com.easybbs.utils.FileUtils;
import com.easybbs.utils.ImageUtils;
import com.easybbs.utils.SysCacheUtils;
import org.springframework.stereotype.Service;

import com.easybbs.entity.query.ForumArticleAttachmentQuery;
import com.easybbs.entity.po.ForumArticleAttachment;
import com.easybbs.entity.vo.PaginationResultVO;
import com.easybbs.entity.query.SimplePage;
import com.easybbs.mappers.ForumArticleAttachmentMapper;
import com.easybbs.service.ForumArticleAttachmentService;
import com.easybbs.utils.StringTools;
import org.springframework.web.multipart.MultipartFile;


/**
 * 文件信息 业务接口实现
 */
@Service("forumArticleAttachmentService")
public class ForumArticleAttachmentServiceImpl implements ForumArticleAttachmentService {

	@Resource
	private ForumBoardService forumBoardService;

	@Resource
	private ForumArticleAttachmentMapper<ForumArticleAttachment, ForumArticleAttachmentQuery> forumArticleAttachmentMapper;

    @Resource
    private ForumArticleMapper<ForumArticle, ForumArticleQuery> forumArticleMapper;

	@Resource
	private UserInfoService userInfoService;

	@Resource
	private FileUtils fileUtils;

	@Resource
	private ImageUtils imageUtils;

	@Resource
	private WebConfig webConfig;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<ForumArticleAttachment> findListByParam(ForumArticleAttachmentQuery param) {
		return this.forumArticleAttachmentMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(ForumArticleAttachmentQuery param) {
		return this.forumArticleAttachmentMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<ForumArticleAttachment> findListByPage(ForumArticleAttachmentQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<ForumArticleAttachment> list = this.findListByParam(param);
		PaginationResultVO<ForumArticleAttachment> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(ForumArticleAttachment bean) {
		return this.forumArticleAttachmentMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<ForumArticleAttachment> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.forumArticleAttachmentMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<ForumArticleAttachment> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.forumArticleAttachmentMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(ForumArticleAttachment bean, ForumArticleAttachmentQuery param) {
		StringTools.checkParam(param);
		return this.forumArticleAttachmentMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(ForumArticleAttachmentQuery param) {
		StringTools.checkParam(param);
		return this.forumArticleAttachmentMapper.deleteByParam(param);
	}

	/**
	 * 根据FileId获取对象
	 */
	@Override
	public ForumArticleAttachment getForumArticleAttachmentByFileId(String fileId) {
		return this.forumArticleAttachmentMapper.selectByFileId(fileId);
	}

	/**
	 * 根据FileId修改
	 */
	@Override
	public Integer updateForumArticleAttachmentByFileId(ForumArticleAttachment bean, String fileId) {
		return this.forumArticleAttachmentMapper.updateByFileId(bean, fileId);
	}

	/**
	 * 根据FileId删除
	 */
	@Override
	public Integer deleteForumArticleAttachmentByFileId(String fileId) {
		return this.forumArticleAttachmentMapper.deleteByFileId(fileId);
	}

	@Override
	public String postArticle(boolean isAdmin, ForumArticle article, ForumArticleAttachment forumArticleAttachment, MultipartFile cover, MultipartFile attachment) {

		// 参数校验
		resetBoardInfo(isAdmin, article);
		Date curDate = new Date();
		String articleId = StringTools.getRandomString(Constants.RANDOM_ARTICLE_ID);
		article.setArticleId(articleId);
		article.setPostTime(curDate);
		article.setLastUpdateTime(curDate);

		if (cover != null) {
			FileUploadDto fileUploadDto = fileUtils.uploadFile2Local(cover, Constants.FILE_FOLDER_IMAGE, FileUploadTypeEnum.ARTICLE_COVER);
			article.setCover(fileUploadDto.getLocalPath());
		}
		if (attachment != null) {
			uploadAttachment(article, forumArticleAttachment, attachment, false);
			article.setAttachmentType(ArticleAttachmentTypeEnum.HAVE_ATTACHMENT.getType());
		} else {
			article.setAttachmentType(ArticleAttachmentTypeEnum.NO_ATTACHMENT.getType());
		}

		// 文章审核信息
		if (isAdmin) {
			article.setStatus(ArticleStatusEnum.AUDIT.getStatus());
		} else {
			SysSetting4AuditDto auditDto = SysCacheUtils.getSysSetting().getAuditSetting();
			article.setStatus(auditDto.getPostAudit() ? ArticleStatusEnum.NO_AUDIT.getStatus() : ArticleStatusEnum.AUDIT.getStatus());
		}

		// 替换图片
		String content = article.getContent();
		if (!StringTools.isEmpty(content)) {
			String month = imageUtils.resetImageHtml(content);
			String replaceMonth = "/" + month + "/";
			content = content.replace(Constants.FILE_FOLDER_TEMP, replaceMonth);
			article.setContent(content);
			String markdownContent = article.getMarkdownContent();
			if (!StringTools.isEmpty(markdownContent)) {
				markdownContent = markdownContent.replace(Constants.FILE_FOLDER_TEMP, replaceMonth);
				article.setMarkdownContent(markdownContent);
			}
		}

		forumArticleMapper.insert(article);

		// 增加积分
		Integer postIntegral = SysCacheUtils.getSysSetting().getPostSetting().getPostIntegral();
		if (postIntegral > 0 && ArticleStatusEnum.AUDIT.getStatus().equals(article.getStatus())) {
			userInfoService.updateUserInfoIntegral(article.getUserId(), UserIntegralOperTypeEnum.POST_ARTICLE, UserIntegralChangeTypeEnum.ADD, postIntegral);
		}

		return articleId;
	}


	private void resetBoardInfo(Boolean isAdmin, ForumArticle formArticle) throws BusinessException {
		ForumBoard pBoard = forumBoardService.getForumBoardByBoardId(formArticle.getpBoardId());
		if (pBoard == null || pBoard.getPostType().equals(Constants.ZERO) && !isAdmin) {
			throw new BusinessException("一级板块不存在");
		}
		formArticle.setpBoardName(pBoard.getBoardName());
		if (formArticle.getBoardId() != null && formArticle.getBoardId() != 0) {
			ForumBoard board = forumBoardService.getForumBoardByBoardId(formArticle.getBoardId());
			if (board == null || board.getPostType().equals(Constants.ZERO) && !isAdmin) {
				throw new BusinessException("二级板块不存在");
			}
			formArticle.setBoardName(board.getBoardName());
		} else {
			formArticle.setBoardId(0);
			formArticle.setBoardName("");
		}
	}

	// 上传附件
	public void uploadAttachment(ForumArticle article, ForumArticleAttachment articleAttachment, MultipartFile file, Boolean isUpdate)  {
		Integer allowSizeMb = SysCacheUtils.getSysSetting().getPostSetting().getAttachmentSize();
		long allowSize = allowSizeMb * Constants.FILE_SIZE_1M;
		if (file.getSize() > allowSize) {
			throw new BusinessException("附件最大只能上传 " + allowSize + " MB");
		}
		// 修改
		ForumArticleAttachment dbInfo = null;
		if (isUpdate) {
			ForumArticleAttachmentQuery articleAttachmentQuery = new ForumArticleAttachmentQuery();
			articleAttachmentQuery.setArticleId(article.getArticleId());
			List<ForumArticleAttachment> articleAttachmentList = this.forumArticleAttachmentMapper.selectList(articleAttachmentQuery);
			if (!articleAttachmentList.isEmpty()) {
				dbInfo = articleAttachmentList.get(0);
				new File(webConfig.getProjectFolder() + Constants.FILE_FOLDER_FILE + Constants.FILE_FOLDER_ATTACHMENT + dbInfo.getFilePath()).delete();
			}
		}

		FileUploadDto fileUploadDto = fileUtils.uploadFile2Local(file, Constants.FILE_FOLDER_ATTACHMENT, FileUploadTypeEnum.ARTICLE_ATTACHMENT);
		if (dbInfo == null) {
			articleAttachment.setFileId(StringTools.getRandomNumber(Constants.LENGTH_15));
			articleAttachment.setArticleId(article.getArticleId());
			articleAttachment.setFileName(fileUploadDto.getOriginalFileName());
			articleAttachment.setFilePath(fileUploadDto.getLocalPath());
			articleAttachment.setFileSize(file.getSize());
			articleAttachment.setDownloadCount(Constants.ZERO);
			articleAttachment.setFileType(AttachmentFileTypeEnum.ZIP.getType());
			articleAttachment.setUserId(article.getUserId());
			forumArticleAttachmentMapper.insert(articleAttachment);
		} else {
			ForumArticleAttachment updateInfo = new ForumArticleAttachment();
			updateInfo.setFileName(fileUploadDto.getOriginalFileName());
			updateInfo.setFileSize(file.getSize());
			updateInfo.setFilePath(fileUploadDto.getLocalPath());
			forumArticleAttachmentMapper.updateByFileId(updateInfo, dbInfo.getFileId());
		}
	}

	@Override
	public void updateArticle(boolean isAdmin, ForumArticle article, ForumArticleAttachment articleAttachment, MultipartFile cover, MultipartFile attachments) {
		ForumArticle dbInfo = forumArticleMapper.selectByArticleId(article.getArticleId());
		if (!isAdmin && !dbInfo.getUserId().equals(article.getUserId())) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		article.setLastUpdateTime(new Date());
		resetBoardInfo(isAdmin, article);
		if (cover != null) {
			FileUploadDto fileUploadDto = fileUtils.uploadFile2Local(cover, Constants.FILE_FOLDER_IMAGE, FileUploadTypeEnum.ARTICLE_COVER);
			article.setCover(fileUploadDto.getLocalPath());
		}
		if (attachments != null) {
			uploadAttachment(article, articleAttachment, attachments, true);
			article.setAttachmentType(ArticleAttachmentTypeEnum.HAVE_ATTACHMENT.getType());
		}
		ForumArticleAttachment dbAttachment = null;
		ForumArticleAttachmentQuery articleAttachmentQuery = new ForumArticleAttachmentQuery();
		articleAttachmentQuery.setArticleId(article.getArticleId());
		List<ForumArticleAttachment> articleAttachmentList = this.forumArticleAttachmentMapper.selectList(articleAttachmentQuery);
		if (!articleAttachmentList.isEmpty()) {
			dbAttachment = articleAttachmentList.get(0);
		}
		if (dbAttachment != null) {
			if (article.getAttachmentType() == Constants.ZERO) {
				new File(webConfig.getProjectFolder() + Constants.FILE_FOLDER_FILE + Constants.FILE_FOLDER_ATTACHMENT + dbAttachment.getFilePath()).delete();
				this.forumArticleAttachmentMapper.deleteByFileId(dbAttachment.getFileId());
			} else {
				// 更新积分
				if (!dbAttachment.getIntegral().equals(articleAttachment.getArticleId())) {
					ForumArticleAttachment integralUpdate = new ForumArticleAttachment();
					integralUpdate.setIntegral(articleAttachment.getIntegral());
					this.forumArticleAttachmentMapper.updateByFileId(integralUpdate, dbAttachment.getFileId());
				}
			}
		}
		// 文章是否需要审核
		if (isAdmin) {
			article.setStatus(ArticleStatusEnum.AUDIT.getStatus());
		} else {
			SysSetting4AuditDto auditDto = SysCacheUtils.getSysSetting().getAuditSetting();
			article.setStatus(auditDto.getPostAudit() ? ArticleStatusEnum.NO_AUDIT.getStatus() : ArticleStatusEnum.AUDIT.getStatus());
		}
		// 替换图片
		String content = article.getContent();
		if (!StringTools.isEmpty(content)) {
			String month = imageUtils.resetImageHtml(content);
			String replaceMonth = "/" + month + "/";
			content = content.replace(Constants.FILE_FOLDER_TEMP, replaceMonth);
			article.setContent(content);
			String markdownContent = article.getMarkdownContent();
			if (!StringTools.isEmpty(markdownContent)) {
				markdownContent = markdownContent.replace(Constants.FILE_FOLDER_TEMP, replaceMonth);
				article.setMarkdownContent(markdownContent);
			}
		}

		this.forumArticleMapper.updateByArticleId(article, article.getArticleId());
	}
}